﻿using BaseMsg;
using K.Client;
using ProtoBuf;
using System;
using System.IO;
using UnityEngine;

public class WebClient : Singleton<WebClient>, IZUpdate
{
    private delegate void MsgModuleDispatcher(Msg msg);
    private MsgModuleDispatcher[] mModuleDispatchers;
    public bool Connected { get; private set; }     //是否连接到网关
    public bool Exception { get; private set; }     // 是否出现异常

    private LuaNetMgr webNetMgr;                    //网关网络管理器
    private bool bConnected;
    private bool bException;

    private string webHost;
    private int webPort;

    public WebClient()
    {
        Connected = false;
        Exception = false;

        LuaMsg.Init(LuaMsgFactory.SerializeHead, LuaMsgFactory.DeserializeHead);
        mModuleDispatchers = new MsgModuleDispatcher[(int)EModuleType.MODULE_END];
    }

    public void InitData(string webHost, int webPort)
    {
        this.webHost = webHost;
        this.webPort = webPort;
    }

    // 参数:是否是首次连接gate
    public bool ConnectWeb()
    {
        EDebug.Log(string.Format("Start Connect to Web {0}:{1}", webHost, webPort));
        webNetMgr = new LuaNetMgr(false);
        try
        {
            webNetMgr.Connect(webHost, webPort);
            ReconnectMgr.GetSingleton().Close();
            ZEventCenter.DispatchEvent(new ZEvent(ConstData.WEBMGR_CONNECT_OK));
        }
        catch (Exception e)
        {
            EDebug.Log(string.Format("web服务器连接失败：\n{0}", e.ToString()));
            ReconnectMgr.GetSingleton().Open();
            return false;
        }
        webNetMgr.MgrName = "webNetMgr";
        EDebug.Log("Web Connection established");

        Exception = false;
        Connected = true;
        Time.timeScale = 1;

        UpdateMgr.GetSingleton().AddUpdate(GetSingleton());
        return true;
    }

    public void ZUpdate()
    {
        if (Connected)
        {
            try
            {
                webNetMgr.RecvMsg(2000, OnWebMsg);
            }
            catch (IOException e)
            {
                EDebug.Log(string.Format("服务器连接断开：\n{0}", e.ToString()));
                OnDisconnect();
                return;
            }
        }
    }

    private int OnWebMsg(LuaMsg luaMsg)
    {
        Msg msg = LuaMsgFactory.LuaMsgToMsg(luaMsg);
        if (msg == null)
        {
            return -1;
        }

        int moduleType = GetMsgModuleType(luaMsg.id);
        // 如果是各模块的消息,那么让模块自己处理
        if (moduleType < 0 || moduleType >= (int)EModuleType.MODULE_END)
        {
            return -1;
        }

        MsgModuleDispatcher dispatcher = mModuleDispatchers[moduleType];
        if (null == dispatcher)
        {
            DefaultDispatcher(msg);
        }
        else
        {
            dispatcher(msg);
        }
        return 0;
    }

    private int GetMsgModuleType(int vMsgID)
    {
        return (vMsgID & 0x0FF000) >> 12;
    }

    private void DefaultDispatcher(Msg msg)
    {

    }

    public void OnDisconnect()
    {
        ReconnectMgr.GetSingleton().Open();
        Connected = false;
        Exception = true;
    }

    public void CloseConnectWebSvr()
    {
        if (Connected)
        {
            Connected = false;
        }
    }

    public void SendToWeb(LuaMsg msg)
    {
        if (Connected)
        {
            try
            {
                webNetMgr.SendMsg(msg);

            }
            catch (Exception e)
            {
                EDebug.Log(string.Format("服务器连接断开：\n{0}", e.ToString()));
                OnDisconnect();
                return;
            }
        }
    }

    public void SendToWeb(Msg msg)
    {
        LuaMsg luaMsg = new LuaMsg();
        SendToWeb(luaMsg);
    }

    public void SendToWeb(int id, IExtensible body, bool bLockScreen)
    {
        SendToWeb(LuaMsgFactory.Create(id, body));
    }

    public void SendToWeb(int id, IExtensible body)
    {
        SendToWeb(LuaMsgFactory.Create(id, body));
    }
}